package com.mylove.textprogressbar;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.NinePatch;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import java.math.BigDecimal;

/**
 * @author myLove
 * @time 2017/12/27 22:04
 * @e-mail love@yanyi.red
 * @overview
 */

public class TextBarView extends View {
    /**
     * 颜色（渐变色的2个点）
     */
    private int[] mColors = {getResources().getColor(R.color.color_green), getResources().getColor(R.color.color_red)};
    private int mColor = getResources().getColor(R.color.color_black);

    private Paint paint;
    /**
     * 间距
     */
    private int padding = 30;

    private float stopY = 0;
    private boolean running = false;
    private MyThread myThread;
    /**
     * 第一等份
     */
    private float num1 = 0;
    /**
     * 第二等份
     */
    private float num2 = 0;
    /**
     * 第三等份
     */
    private float num3 = 0;
    /**
     * 进度条当前数值
     */
    private float size = 0;
    /**
     * 进度
     */
    private float num = 0;
    private float linkNum1 = 0;
    private float linkNum2 = 0;
    private float linkNum3 = 0;
    private float maxLength = 0;
    /**
     * 底部第一排介绍文字
     **/
    private String msg1 = "";
    private String msg2 = "";
    private String msg3 = "";

    private float size1 = 0;
    private float size2 = 0;
    private float size3 = 0;
    private float size4 = 0;

    private int time = 5;
    private int sleep = 10;

    private float s1 = 0;
    private float s2 = 0;

    public TextBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public TextBarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        paint = new Paint();
    }

    /**
     * 进度条开始加载进度
     */
    public void start() {
        running = true;
        s1 = 0;
        s2 = 0;
        stopY = 0;
        if (myThread != null) {
            myThread.start();
        }
    }

    /**
     * 停止进度条加载进度
     */
    public void stop() {
        running = false;
        s1 = 0;
        s2 = 0;
        myThread = new MyThread();
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);
        linkNum1 = (getWidth()) / 2;
        linkNum2 = ((getWidth()) / 2 - 2 * padding) / 2 + linkNum1;
        linkNum3 = getWidth() - 2 * padding;
        maxLength = getWidth() - padding;
        if (myThread == null) {
            myThread = new MyThread();
            myThread.start();
        } else {
            drawRect(canvas);
        }
    }

    private void drawRect(Canvas canvas) {
        //设置画笔为无锯齿
        paint.setAntiAlias(true);
        //實心效果
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(mColor);
        //设置背景
        BitmapDrawable drawBg = (BitmapDrawable) getResources().getDrawable(R.mipmap.bg);
        Bitmap bBg = drawBg.getBitmap();
        Rect rBg = new Rect(0, padding, getWidth() - 1, getHeight() - 1 - padding * 2);
        canvas.drawBitmap(bBg, null, rBg, null);
        //中间线条
        canvas.drawLine(linkNum1, padding, (getWidth() - 1) / 2, getHeight() - 1 - padding * 2, paint);
        //倒数第二根线条
        canvas.drawLine(linkNum2, padding, linkNum2, getHeight() - 1 - padding * 2, paint);
        //最后线条
        canvas.drawLine(linkNum3, padding, linkNum3, getHeight() - 1 - padding * 2, paint);
        //设置进度条背景
        BitmapDrawable bmpDrawBg = (BitmapDrawable) getResources().getDrawable(R.mipmap.bar_bg);
        Bitmap bitmapBg = bmpDrawBg.getBitmap();
        Rect rectBg = new Rect(padding, padding * 2, getWidth() - 1 - padding, getHeight() - 1 - 3 * padding);
        canvas.drawBitmap(bitmapBg, null, rectBg, null);
        //设置渐变色区域
//        int count = mColors.length;
//        @SuppressLint("DrawAllocation")
//        int[] colors = new int[count];
//        System.arraycopy(mColors, 0, colors, 0, count);
//        @SuppressLint("DrawAllocation")
//        LinearGradient shader1 = new LinearGradient(padding, (getHeight() - 1 - padding) / 2 + padding, maxLength - 1, (getHeight() - 1 - padding) / 2 + padding, colors, null,
//                Shader.TileMode.CLAMP);
//        Paint mPaint = new Paint();
//        mPaint.setShader(shader1);
        //画出渐变色
        if (stopY >= maxLength - padding) {
            stopY = stopY - 1;
        }
//        canvas.drawRect(padding, padding * 2, stopY + padding, getHeight() - 1 - 3 * padding, mPaint);
        BitmapDrawable bmpDraw = (BitmapDrawable) getResources().getDrawable(R.mipmap.bar);
        Bitmap bitmap = bmpDraw.getBitmap();
        Rect rect = new Rect(padding, padding * 2, getWidth() - 1 - padding, getHeight() - 1 - 3 * padding);
        canvas.drawBitmap(bitmap, null, rect, null);
        //底部第一排第一个文字
        paint.setTextSize(25);
        paint.setTextAlign(Paint.Align.CENTER);
        canvas.drawText(msg1, (getWidth() - 1) / 2 - ((getWidth() - 1) / 2 - padding) / 2 + padding, getHeight() - 2.2f * padding, paint);
        canvas.drawText(msg2, (getWidth() - 1) / 2 + (getWidth() - 1 - padding * 2) / 8, getHeight() - 2.2f * padding, paint);
        canvas.drawText(msg3, (getWidth() - 1 - padding * 2) / 4 * 3 + padding + (getWidth() - 1 - padding * 2) / 8, getHeight() - 2.2f * padding, paint);
        BitmapDrawable bmpDrawSan = (BitmapDrawable) getResources().getDrawable(R.mipmap.san);
        Bitmap bitmapSan = bmpDrawSan.getBitmap();
        Rect rectSan1 = new Rect((int) ((getWidth() - 1) / 2 - 0.5f * padding), getHeight() - 1 - 2 * padding + 5, (int) ((getWidth() - 1) / 2 + 0.5f * padding), getHeight() - 1 - padding - 5);
        canvas.drawBitmap(bitmapSan, null, rectSan1, null);
        Rect rectSan2 = new Rect((int) (linkNum2 - 0.5f * padding), getHeight() - 1 - 2 * padding + 5, (int) (linkNum2 + 0.5f * padding), getHeight() - 1 - padding - 5);
        canvas.drawBitmap(bitmapSan, null, rectSan2, null);
        Rect rectSan3 = new Rect((int) (linkNum3 - 0.5f * padding), getHeight() - 1 - 2 * padding + 5, (int) (linkNum3 + 0.5f * padding), getHeight() - 1 - padding - 5);
        canvas.drawBitmap(bitmapSan, null, rectSan3, null);
        canvas.drawText("¥" + num1, (getWidth() - 1) / 2, getHeight() - 1 - 0.5f * padding, paint);
        canvas.drawText("¥" + num2, linkNum2, getHeight() - 1 - 0.5f * padding, paint);
        canvas.drawText("¥" + num3, linkNum3, getHeight() - 1 - 0.5f * padding, paint);
        String str = "¥00.00";
        float measureText = paint.measureText(str);
        BitmapDrawable drawable = (BitmapDrawable) getResources().getDrawable(R.mipmap.msg);
        Bitmap drawableBitmap = drawable.getBitmap();
        Rect rect1 = new Rect((int) (stopY - measureText / 2 - 20 + padding), 0, (int) (stopY + measureText / 2 + 20 + padding), padding * 2 - 5);
        canvas.drawBitmap(drawableBitmap, null, rect1, null);
        float v = stopY + padding;
        paint.setColor(getResources().getColor(R.color.color_find_gray));
        canvas.drawText("¥" + size, v, padding, paint);
//        BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.mipmap.pro);
//        Bitmap db = bd.getBitmap();
//        Bitmap db = BitmapFactory.decodeResource(getResources(), R.drawable.pro);
        Rect r = new Rect(padding, padding * 2, (int) (stopY + padding), getHeight() - 1 - 3 * padding);
//        canvas.drawBitmap(db, null, r, null);
        drawNinepath(canvas, R.drawable.pro, r);
        if (size >= num) {
            stop();
        }
    }

    public void drawNinepath(Canvas c, int id, Rect r1) {
        Bitmap bmp = BitmapFactory.decodeResource(getResources(), id);

        NinePatch patch = new NinePatch(bmp, bmp.getNinePatchChunk(), null);
        patch.draw(c, r1);
    }

    private class MyThread extends Thread {
        @Override
        public void run() {
            super.run();
            time *= (1000 / sleep);
            size = 0;
            if (num <= num1) {
                setUI1();
            } else if (num > num1 && num <= num2) {
                setUI2();
            } else if (num > num2 && num <= num3) {
                setUI3();
            } else {
                setUI4();
            }
        }
    }

    private void setUI1() {
        float f = linkNum1 - padding;
        float v = size1 / num1 * f;
        float v1 = v / time;
        float i = 0;
        while (running) {
            s1 = i;
            if (s1 > s2) {
                stopY = s1;
            }
            s2 = stopY;
            setFloat(i / f * num1);
            if (i < v) {
                i += v1;
            } else {
                setFloat(num);
                running = false;
            }
            try {
                Thread.sleep(sleep);
            } catch (Exception e) {
                e.printStackTrace();
            }
            postInvalidate();
        }
    }

    private void setUI2() {
        float f1 = linkNum1 - padding;
        float f2 = size2 / (num2 - num1) * (linkNum2 - linkNum1);
        float v = f1 + f2;
        float v1 = v / time;
        float i = 0;
        while (running) {
            s1 = i;
            if (s1 > s2) {
                stopY = s1;
            }
            s2 = stopY;
            if (i <= f1) {
                setFloat(i / f1 * num1);
            } else {
                setFloat((i - f1) / (linkNum2 - linkNum1) * (num2 - num1) + num1);
            }
            if (i < v) {
                i += v1;
            } else {
                setFloat(num);
                running = false;
            }
            try {
                Thread.sleep(sleep);
            } catch (Exception e) {
                e.printStackTrace();
            }
            postInvalidate();
        }
    }

    private void setUI3() {
        float f1 = linkNum1 - padding;
        float f2 = linkNum2 - linkNum1;
        float f3 = size3 / (num3 - num2) * (linkNum3 - linkNum2);
        float v = f1 + f2 + f3;
        float v1 = v / time;
        float i = 0;
        while (running) {
            s1 = i;
            if (s1 > s2) {
                stopY = s1;
            }
            s2 = stopY;
            if (i <= f1) {
                setFloat(i / f1 * num1);
            } else if (i > f1 && i <= f2 + f1) {
                setFloat((i - f1) / f2 * (num2 - num1) + num1);
            } else {
                setFloat((i - f1 - f2) / (linkNum3 - linkNum2) * (num3 - num2) + num2);
            }
            if (i < v) {
                i += v1;
            } else {
                setFloat(num);
                running = false;
            }
            try {
                Thread.sleep(sleep);
            } catch (Exception e) {
                e.printStackTrace();
            }
            postInvalidate();
        }
    }

    private void setUI4() {
        float f1 = linkNum1 - padding;
        float f2 = linkNum2 - linkNum1;
        float f3 = linkNum3 - linkNum2;
        float f4 = size4 / (num - num3) * padding;
        float v = f1 + f2 + f3 + f4;
        float v1 = v / time;
        float i = 0;
        while (running) {
            s1 = i;
            if (s1 > s2) {
                stopY = s1;
            }
            s2 = stopY;
            if (i <= f1) {
                setFloat(i / f1 * num1);
            } else if (i > f1 && i <= f2 + f1) {
                setFloat((i - f1) / f2 * (num2 - num1) + num1);
            } else if (i > f1 + f2 && i <= f1 + f2 + f3) {
                setFloat((i - f1 - f2) / (linkNum3 - linkNum2) * (num3 - num2) + num2);
            } else {
                setFloat((i - f1 - f2 - f3) / padding * (num - num3) + num3);
            }
            if (i < v) {
                i += v1;
            } else {
                v(size);
                setFloat(num);
                running = false;
            }
            try {
                Thread.sleep(sleep);
            } catch (Exception e) {
                e.printStackTrace();
            }
            postInvalidate();
        }
    }

    private void setFloat(float f) {
        BigDecimal b = new BigDecimal(f);
        size = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
    }

    /**
     * 设置分段线的标签
     *
     * @param num1
     * @param num2
     * @param num3
     * @return
     */
    public TextBarView setNum(float num1, float num2, float num3) {
        this.num1 = num1;
        this.num2 = num2;
        this.num3 = num3;
        return this;
    }

    /**
     * 设置金额
     *
     * @param num
     * @return
     */
    public TextBarView setSize(float num) {
        this.num = num;
        if (num1 > 0) {
            if (num <= num1) {
                size1 = num;
            } else if (num > num1 && num <= num2) {
                size1 = num1;
                size2 = num - num1;
            } else if (num > num2 && num <= num3) {
                size1 = num1;
                size2 = num2 - num1;
                size3 = num - num2;
            } else {
                size1 = num1;
                size2 = num2 - num1;
                size3 = num3 - num2;
                size4 = num - num3;
            }
        }
        return this;
    }

    /**
     * 设置每块的标签
     *
     * @param msg1
     * @param msg2
     * @param msg3
     * @return
     */
    public TextBarView setMsg(String msg1, String msg2, String msg3) {
        this.msg1 = msg1;
        this.msg2 = msg2;
        this.msg3 = msg3;
        return this;
    }

    /**
     * 設置漸變顔色
     *
     * @param color
     * @return
     */
    public TextBarView setColor(int[] color) {
        this.mColors = color;
        return this;
    }

    public TextBarView setTime(int time) {
        if (time <= 0) {
            throw new NullPointerException("时间不能为" + time);
        } else {
            this.time = time;
        }
        return this;
    }

    private void v(Object... msg) {
        int i = 0;
        for (Object aMsg : msg) {
            Log.v("***" + i, aMsg.toString());
            ++i;
        }
    }

    private void i(String tag, Object... msg) {
        for (Object aMsg : msg) {
            Log.i(tag, aMsg.toString());
        }
    }
}
